package com.dingreading.cloud.mall.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.dto.LoginDataDto;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.common.util.qyweixin.AccessTokenDto;
import com.dingreading.cloud.common.util.qyweixin.QyWeiXinUtil;
import com.dingreading.cloud.common.util.qyweixin.QyWeixinMsg;
import com.dingreading.cloud.mall.dto.FormDto;
import com.dingreading.cloud.mall.dto.OrderFormDto;
import com.dingreading.cloud.mall.dto.StockOutDeliveryDto;
import com.dingreading.cloud.mall.entity.*;
import com.dingreading.cloud.mall.service.*;
import com.dingreading.cloud.mall.util.LoginInfoUtil;
import com.dingreading.cloud.mall.util.OrderFormV3Util;
import com.dingreading.cloud.mall.util.PurchaseUtil;
import com.dingreading.cloud.mall.util.ShopCartUtilV2;
import com.dingreading.cloud.mall.util.redis.RedisService;
import com.google.common.collect.Lists;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/cancel/orderForm/v3")
@Api(tags = "商城-商城订单管理v3(废弃)")
public class FrontOrderFormControllerV3 {

    @Value("${serverUrl}")
    private String serverUrl;
    @Value("${qyweixin.corpid}")
    private String corpid;
    @Value("${qyweixin.secret}")
    private String secret;
    @Value("${qyweixin.agentid}")
    private String agentid;
    @Value("${qyweixin.mallchatid}")
    private String mallchatid;
    @Value("${qyweixin.thirdUserid}")
    private String thirdUserid;
    @Value("${qyweixin.financechatid}")
    private String financechatid;


    @Resource
    protected OrderFormService orderFormService;
    @Resource
    protected OrderFormLogService orderFormLogService;
    @Resource
    protected OrderFormImageService orderFormImageService;
    @Resource
    protected WhStockOutService stockOutService;
    @Resource
    protected ShopCartService shopCartService;
    @Resource
    protected GoodsService goodsService;
    @Resource
    protected GoodsTypeService goodsTypeService;
    @Resource
    protected DeliveryAddressService deliveryAddressService;
    @Resource
    protected WhStockOutDeliveryService stockOutDeliveryService;
    @Resource
    protected StoresService storesService;
    @Resource
    protected GoodsTypeComboService goodsTypeComboService;
    @Resource
    protected WhStockOutDeliveryImgService stockOutDeliveryImgService;
    @Resource
    protected StoreGoodsDiscountService storeGoodsDiscountService;
    @Resource
    private RedisService redisService;


    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList", produces = "application/json; charset=UTF-8")
    public R<Object> pageList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @RequestParam(value = "keyword", required = false) @ApiParam(value = "订单号/用户姓名/手机号") String keyword,
            @RequestParam(value = "status", required = false) @ApiParam(value = "状态 0.取消 1.完成 2.待确认 3.待付款 4.待发货") Integer status
    ) {
        Page<OrderFormDto> pageList = orderFormService.staffPageList(pageUtil, storeUid, staffUid, keyword, status);

        List<OrderFormDto> list = pageList.getRecords();
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> codes = list.stream().map(OrderFormDto::getCode).collect(Collectors.toList());
            // 按订单编号获取购物车记录去除组合子商品记录
            List<ShopCart> shopCarts = shopCartService.mainListByCodeIn(codes);
            Map<String, List<ShopCart>> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(shopCarts))
                map = shopCarts.stream().collect(Collectors.groupingBy(ShopCart::getCode));

            for (OrderFormDto form : list) {
                form.setShopCartList(map.get(form.getCode()));
            }
        }

        Map<String, String> numDtos = orderFormService.getStatusNum(storeUid, staffUid);

        PageDataDto data = new PageDataDto();
        data.setTotal(pageList.getTotalRow());
        data.setList(list);
        data.setData(numDtos);
        return R.ok(data);
    }


    @ApiOperation(value = "获取订单详情")
    @PostMapping(value = "/get", produces = "application/json; charset=UTF-8")
    public R<Object> get(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店信息获取失败");

        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (form == null)
            return R.fail("订单获取失败");

        // 购物车商品记录
        List<ShopCart> carts = shopCartService.mainListByStaffUidAndCode(staffUid, code);

        // 查看银行转账截图
        List<OrderFormImage> imageList = orderFormImageService.getByOrderCode(code);

        // 获取快递信息
        JSONArray express = new JSONArray();
        if (StringUtils.isNotBlank(form.getExpressCode())) {
            // 旧版订单快递信息
            List<String> strings = Arrays.stream(StringUtils.split(form.getExpressCode(), ";")).collect(Collectors.toList());
            for (String string : strings) {
                if (StringUtils.isNotBlank(string)) {
                    String[] split = StringUtils.split(string, "*");
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("expressCode", split[0]);
                    jsonObject.put("expressName", split[1]);
                    jsonObject.put("expressPrice", null);
                    jsonObject.put("expressTime", null);
                    jsonObject.put("packageNum", null);
                    jsonObject.put("goodsList", new JSONArray());
                    express.add(jsonObject);
                }
            }
        }

        // 获取发货完成的出库单
        List<WhStockOut> outList = stockOutService.getByOrderCodeV2(code);
        if (CollectionUtils.isNotEmpty(outList)) {
            List<String> outCodes = outList.stream().map(WhStockOut::getOutCode).collect(Collectors.toList());
            List<WhStockOutDelivery> deliveryList = stockOutDeliveryService.listByOutCodes(outCodes);
            if (CollectionUtils.isNotEmpty(deliveryList)) {
                List<Long> deliveryIdList = deliveryList.stream().map(WhStockOutDelivery::getId).collect(Collectors.toList());
                List<WhStockOutDeliveryImg> deliveryImgList = stockOutDeliveryImgService.listByDeliveryIdIn(deliveryIdList);
                Map<Long, List<WhStockOutDeliveryImg>> imgMap = new HashMap<>();
                if (CollectionUtils.isNotEmpty(deliveryImgList)) {
                    imgMap = deliveryImgList.stream().collect(Collectors.groupingBy(WhStockOutDeliveryImg::getDeliveryId));
                }

                for (WhStockOutDelivery delivery : deliveryList) {
                    StockOutDeliveryDto deliveryObj = PurchaseUtil.getDeliveryObj(delivery, imgMap.get(delivery.getId()));
                    express.add(deliveryObj);
                }
            }
        }

        List<OrderFormLog> logs = null;
        if (AccountUtil.isSelfStore(stores.getOperationType())) {
            // 自营门店获取订单操作日志
            logs = orderFormLogService.getByCode(code);
        }

        FormDto dto = new FormDto();
        dto.setOrderForm(form);
        dto.setShopCartList(carts);
        dto.setExpressArr(express);
        dto.setImageList(imageList);
        dto.setLogList(logs);
        return R.ok(dto);
    }


    @ApiOperation(value = "获取订单的状态 ,返回4支付成功")
    @PostMapping(value = "/getFormStatus", produces = "application/json; charset=UTF-8")
    public R<Object> getFormStatus(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        Integer status = orderFormService.getFormStatus(staffUid, code);

        return R.ok(status);
    }


    @ApiOperation(value = "判断能否取消订单")
    @PostMapping(value = "/judgeCancel", produces = "application/json; charset=UTF-8")
    public R<Object> judgeCancel(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (null == form)
            return R.fail("订单获取失败");

        Integer status = form.getStatus();

        ArrayList<Integer> statusList = Lists.newArrayList(EnumType.OrderForm.WAIT_CONFIRM.getType(), EnumType.OrderForm.WAIT_PAY.getType());
        if (!statusList.contains(status))
            return R.fail("订单状态不符合订单状态：" + EnumType.OrderForm.getStatus(status));

        return R.ok();
    }


    @ApiOperation(value = "取消订单")
    @PostMapping(value = "/cancel", produces = "application/json; charset=UTF-8")
    public R<Object> cancel(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (form == null)
            return R.fail("订单获取失败");

        Integer status = form.getStatus();

        ArrayList<Integer> statusList = Lists.newArrayList(EnumType.OrderForm.WAIT_CONFIRM.getType(), EnumType.OrderForm.WAIT_PAY.getType());
        if (!statusList.contains(status))
            return R.fail("订单状态不符合订单状态：" + EnumType.OrderForm.getStatus(status));

        boolean l = this.orderFormService.cancelOrder(staffUid, code);
        if (!l)
            return R.fail("修改失败订单状态：" + EnumType.OrderForm.getStatus(form.getStatus()));

        // 取消购物车记录
        shopCartService.cancelShopCarts(staffUid, code);

        // 添加订单操作记录
        OrderFormLog log = OrderFormV3Util.newStaffLog(form.getCode(), staffUid, staffName,
                EnumType.OrderForm.CANCEL.getType(), "取消订单", remark);
        orderFormLogService.saveOrUpdate(log);

        // 删除redis过期自动取消的商城订单号
        OrderFormV3Util.deleteMallCodeFromRedisExpire(code);

        return R.ok();
    }


    @ApiOperation(value = "修改送货地址")
    @PostMapping(value = "/editAddress", produces = "application/json; charset=UTF-8")
    public R<Object> editAddress(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "送货地址id") @RequestParam(value = "deliveryId") Long deliveryId
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (form == null)
            return R.fail("订单获取失败");

        DeliveryAddress delivery = deliveryAddressService.getById(deliveryId);
        if (delivery == null)
            return R.fail("收货地址获取失败");

        boolean l = orderFormService.updateAddress(staffUid, code, delivery);
        if (!l)
            return R.fail("修改失败订单状态：" + EnumType.OrderForm.getStatus(form.getStatus()));

        return R.ok();
    }


    @ApiOperation(value = "删除")
    @PostMapping(value = "/delete", produces = "application/json; charset=UTF-8")
    public R<Object> delete(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (form == null)
            return R.fail("订单获取失败");

        long l = orderFormService.deleteByStaffIdAndCode(staffUid, code);
        if (l <= 0)
            return R.fail("删除失败订单状态：" + EnumType.OrderForm.getStatus(form.getStatus()));

        shopCartService.deleteByStaffIdAndCode(staffUid, code);
        return R.ok();
    }


    @ApiOperation(value = "重新加入购物车")
    @PostMapping(value = "/againAddShopCart", produces = "application/json; charset=UTF-8")
    public R<Object> againAddShopCart(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店信息获取失败");
        String storesCorpUid = stores.getCorpUid();
        String storesSubjectType = stores.getSubjectType();

        // 轻量门店的商品折扣规则
        StoreGoodsDiscount storeGoodsDiscount = storeGoodsDiscountService.getEnabledDiscount(storeUid);
        Double storeGoodsDiscountRate = null;
        if (storeGoodsDiscount != null) {
            storeGoodsDiscountRate = storeGoodsDiscount.getDiscountRate();
        }

        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (null == form)
            return R.fail("订单获取失败");
        if (!form.getStatus().equals(EnumType.OrderForm.CANCEL.getType()))
            return R.fail("不是取消的订单不能操作");

        List<ShopCart> mainAndChildCartList = shopCartService.mainListAndChildListByCode(code);
        if (CollectionUtils.isEmpty(mainAndChildCartList))
            return R.fail("订单的购物车信息不存在");

        Set<Long> goodsIds = new HashSet<>();
        Set<Long> goodsTypeIds = new HashSet<>();
        Set<Long> mainGoodsTypeIds = new HashSet<>();
        List<ShopCart> mainCartList = new ArrayList<>();

        for (ShopCart cart : mainAndChildCartList) {
            // 商品id集合
            goodsIds.add(cart.getGoodsId());
            goodsTypeIds.add(cart.getGoodsTypeId());

            // 组合商品的商品配置
            if (cart.getComboType().equals(1))
                mainGoodsTypeIds.add(cart.getMainGoodsTypeId());

            // 父购物车商品
            if (cart.getMainComboType().equals(0) || (cart.getComboType().equals(1) && cart.getMainComboType().equals(1)))
                mainCartList.add(cart);
        }

        // 组合商品的商品配置
        Map<Long, List<GoodsTypeCombo>> goodsTypeComboMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(mainGoodsTypeIds)) {
            List<GoodsTypeCombo> goodsTypeComboList = goodsTypeComboService.listByMainGoodsTypeIds(new ArrayList<>(mainGoodsTypeIds));
            if (CollectionUtils.isEmpty(goodsTypeComboList))
                return R.fail("组合商品的商品配置获取失败");
            goodsTypeComboMap = goodsTypeComboList.stream().collect(Collectors.groupingBy(GoodsTypeCombo::getMainGoodsTypeId));
        }

        // 获取商品和商品规格信息
        List<Long> goodsIdList = new ArrayList<>(goodsIds);
        List<Long> goodsTypeIdList = new ArrayList<>(goodsTypeIds);

        List<Goods> goodsList = goodsService.listByIds(goodsIdList);
        if (CollectionUtils.isEmpty(goodsList) || goodsIdList.size() != goodsList.size())
            return R.fail("组合商品内的商品获取失败");
        List<GoodsType> goodsTypeList = goodsTypeService.listByIds(goodsTypeIdList);
        if (CollectionUtils.isEmpty(goodsTypeList) || goodsTypeIdList.size() != goodsTypeList.size())
            return R.fail("组合商品内的商品规格获取失败");

        Map<Long, Goods> goodsMap = goodsList.stream().collect(Collectors.toMap(Goods::getId, Function.identity()));
        Map<Long, GoodsType> goodsTypeMap = goodsTypeList.stream().collect(Collectors.toMap(GoodsType::getId, Function.identity()));

        for (GoodsType goodsType : goodsTypeList) {
            if (goodsType.getEnabled().equals(0)) {
                Goods childGoods = goodsMap.get(goodsType.getGoodsId());
                return R.fail("商品规格已下架" + childGoods.getName() + "/" + goodsType.getName());
            }
        }

        List<ShopCart> newCartList = new ArrayList<>();
        for (ShopCart cart : mainCartList) {
            Goods goods = goodsMap.get(cart.getGoodsId());
            GoodsType goodsType = goodsTypeMap.get(cart.getGoodsTypeId());
            if (goods == null || goodsType == null)
                return R.fail("购物车的商品和商品规格获取失败");

            // 查询购物车内是否有该商品规格
            ShopCart data = shopCartService.getByStaffIdAndGoodsIdAndTypeId(storeUid, staffUid, cart.getGoodsId(), cart.getGoodsTypeId(), cart.getMainComboType(), cart.getComboType());

            double totalWeight = 0;
            int paymentMethod = 1;
            String mainUid = data == null ? KitUtil.getUuid() : data.getUid();

            // 如果是组合商品，则修改子购物车记录的购买数量
            if (cart.getMainComboType().equals(1) && cart.getComboType().equals(1)) {
                List<GoodsTypeCombo> comboList = goodsTypeComboMap.get(cart.getGoodsTypeId());
                Map<Long, GoodsTypeCombo> comboMap = comboList.stream().collect(Collectors.toMap(GoodsTypeCombo::getGoodsTypeId, Function.identity()));

                List<ShopCart> childCartList = shopCartService.childListByStoreUidAndStaffUidAndUid(storeUid, staffUid, mainUid);
                if (CollectionUtils.isEmpty(childCartList)) {
                    for (Map.Entry<Long, GoodsTypeCombo> entry : comboMap.entrySet()) {
                        GoodsTypeCombo goodsTypeCombo = entry.getValue();

                        Goods childGoods = goodsMap.get(goodsTypeCombo.getGoodsId());
                        GoodsType childGoodsType = goodsTypeMap.get(goodsTypeCombo.getGoodsTypeId());

                        // 包含有银行转账
                        if (paymentMethod == 1 && childGoods.getPaymentMethod().equals(2))
                            paymentMethod = 2;

                        int buyNum = cart.getBuyNum() * goodsTypeCombo.getNum();
                        ShopCart childCart = ShopCartUtilV2.newChildComboShopCart(
                                childGoods, childGoodsType, storesCorpUid, storeUid, staffUid,
                                EnumType.ShopCartType.ADD.getType(), cart.getMainComboType(), KitUtil.getUuid(), buyNum, staffUid, staffName,
                                mainUid, goods.getId(), goods.getName(), goodsType.getId(), goodsType.getName(),
                                null
                        );

                        totalWeight = DoubleUtil.sum(totalWeight, childCart.getTotalWeight());

                        newCartList.add(childCart);
                    }
                } else {
                    // 获取购物车里的组合商品内的商品购物车记录
                    for (ShopCart childCart : childCartList) {
                        GoodsTypeCombo goodsTypeCombo = comboMap.get(childCart.getGoodsTypeId());

                        Goods childGoods = goodsMap.get(childCart.getGoodsId());
                        GoodsType childGoodsType = goodsTypeMap.get(childCart.getGoodsTypeId());

                        // 包含有银行转账
                        if (paymentMethod == 1 && childGoods.getPaymentMethod().equals(2))
                            paymentMethod = 2;

                        int buyNum = cart.getBuyNum() * goodsTypeCombo.getNum() + childCart.getBuyNum();
                        // 修改组合商品规格的购物车记录
                        ShopCartUtilV2.mdyShopCart(
                                childCart, childGoods, childGoodsType, buyNum, staffUid, staffName, null
                        );

                        totalWeight = DoubleUtil.sum(totalWeight, childCart.getTotalWeight());
                        newCartList.add(childCart);
                    }
                }
            }

            if (data == null) {
                // 购物车内没有商品
                if (cart.getComboType().equals(0)) {
                    // 新增正常商品的购物车记录
                    data = ShopCartUtilV2.newShopCart(
                            goods, goodsType, storesCorpUid, storeUid, staffUid,
                            EnumType.ShopCartType.ADD.getType(), cart.getMainComboType(), mainUid, cart.getBuyNum(),
                            staffUid, staffName, null, storeGoodsDiscountRate
                    );
                } else {
                    // 新增组合商品的购物车记录
                    data = ShopCartUtilV2.newMainComboShopCart(
                            goods, goodsType, storesCorpUid, storeUid, staffUid,
                            EnumType.ShopCartType.ADD.getType(), cart.getMainComboType(), mainUid, cart.getBuyNum(),
                            staffUid, staffName, paymentMethod, totalWeight, null,
                            storeGoodsDiscountRate
                    );
                }
            } else {
                // 购物车内有商品
                int buyNum = cart.getBuyNum() + data.getBuyNum();
                // 修改组合商品规格的购物车记录
                if (cart.getComboType().equals(0))
                    ShopCartUtilV2.mdyShopCart(
                            data, goods, goodsType, buyNum, staffUid, staffName, storeGoodsDiscountRate
                    );
                else
                    ShopCartUtilV2.mdyMainComboShopCart(
                            data, goods, goodsType, buyNum, paymentMethod, totalWeight, staffUid, staffName,
                            storeGoodsDiscountRate
                    );
            }
            newCartList.add(data);
        }

        // 验证购物车商品能否重新加入购物车
        String resultMsg = OrderFormV3Util.verifyAgainAddShopCarts(AccountUtil.isSelfStore(stores.getOperationType()), false,
                newCartList, goodsMap, goodsTypeMap, goodsTypeIdList);
        if (StringUtils.isNotBlank(resultMsg))
            return R.fail(resultMsg);

        shopCartService.saveOrUpdateBatch(newCartList);
        return R.fail(0, "重新加入购物车成功");
    }


    @ApiOperation(value = "银行转账，上传银行转账截图")
    @PostMapping(value = "/uploadBankPayImg", produces = "application/json; charset=UTF-8")
    public R<Object> uploadBankPayImg(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "图片文件") @RequestPart(value = "file") MultipartFile file
    ) throws Exception {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (null == form)
            return R.fail("订单获取失败");
        if (!form.getStatus().equals(EnumType.OrderForm.WAIT_PAY.getType()))
            return R.fail("订单状态不符合");

        long imgNum = orderFormImageService.getImgNum(code);
        if (imgNum >= 10)
            return R.fail("图片最多上传10张");

        // 上传图片到服务器
        R<String> r = LocalFileUtil.uploadImg(LocalFileUtil.orderFormBaseDir, file);
        if (R.isError(r))
            return R.fail(r.getMsg());

        String imageUrl = r.getData();
        OrderFormImage image = new OrderFormImage();
        image.setOrderCode(code);
        image.setStaffUid(staffUid);
        image.setImgUrl(imageUrl);
        orderFormImageService.saveOrUpdate(image);

        JSONObject object = new JSONObject();
        object.put("id", image.getId());
        object.put("imgUrl", imageUrl);
        return R.ok(object);
    }


    @ApiOperation(value = "删除订单的银行转账截图")
    @PostMapping(value = "/dropBankPayImg", produces = "application/json; charset=UTF-8")
    public R<Object> dropBankPayImg(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "图片id") @RequestParam(value = "imgId") Long imgId
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (form == null)
            return R.fail("订单获取失败");
        if (!form.getStatus().equals(EnumType.OrderForm.WAIT_PAY.getType()))
            return R.fail("订单状态不符合");

        OrderFormImage image = orderFormImageService.getById(imgId);
        if (null == image)
            return R.fail("图片不存在");

        long l = orderFormImageService.dropByOrderCodeAndId(code, imgId);
        if (l <= 0)
            return R.failDel();

        // 删除服务器上的截图
        if (StringUtils.isNotBlank(image.getImgUrl())) {
            LocalFileUtil.deleteImg(LocalFileUtil.orderFormBaseDir, image.getImgUrl());
        }
        return R.ok();
    }


    @ApiOperation(value = "获取订单的银行转账截图")
    @PostMapping(value = "/getBankPayImg", produces = "application/json; charset=UTF-8")
    public R<Object> getBankPayImg(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (null == form)
            return R.fail("订单获取失败");
        if (!form.getStatus().equals(EnumType.OrderForm.WAIT_PAY.getType()))
            return R.fail("订单状态不符合");

        List<OrderFormImage> list = orderFormImageService.getByOrderCode(code);
        return R.ok(list);
    }


    @ApiOperation(value = "申请银行转账")
    @PostMapping(value = "/bankPay", produces = "application/json; charset=UTF-8")
    public R<Object> bankPay(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) throws Exception {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (null == form)
            return R.fail("获取订单失败");
        if (!form.getStatus().equals(EnumType.OrderForm.WAIT_PAY.getType()))
            return R.fail("订单状态不符合");

        long imgNum = orderFormImageService.getImgNum(code);
        if (imgNum == 0)
            return R.fail("请先上传银行转账图片");
        if (imgNum > 10)
            return R.fail("银行转账图片最多上传10张");

        // 验证订单有效性
        String msg = OrderFormV3Util.verifyOrderForm(form, true, AccountUtil.isSelfStore(loginDto.getCurrentOperationType()));
        if (StringUtils.isNotBlank(msg))
            return R.fail(msg);

        // 订单更新支付渠道和支付时间
        String payTime = DateUtil.getNowDatetimeStr();
        boolean l = orderFormService.applyBankPay(form.getStoreUid(), code, payTime);
        if (!l)
            return R.fail("申请银行转账失败");

        // 添加操作日志
        OrderFormLog log = OrderFormV3Util.newStaffLog(code, staffUid, staffName,
                EnumType.OrderForm.APPLY_BANKPAY.getType(), "上传图片，申请银行转账", "");
        orderFormLogService.saveOrUpdate(log);

        // 删除redis过期自动取消的商城订单号
        OrderFormV3Util.deleteMallCodeFromRedisExpire(code);

        // 企业微信获取access_token
        String accessToken = (String) redisService.get(RedisParam.QYWEINXIN_ACCESS_TOKEN);
        if (StringUtils.isBlank(accessToken)) {
            AccessTokenDto dto = QyWeiXinUtil.getAccessToken(corpid, secret);
            if (dto != null) {
                accessToken = dto.getAccess_token();
                int expires_in = dto.getExpires_in();
                // redis缓存accessToken
                redisService.set(RedisParam.QYWEINXIN_ACCESS_TOKEN, accessToken, expires_in);
            }
        }

        // 发送钉钉机器人群消息通知
        if (AccountUtil.isJointOperation(loginDto.getCurrentOperationType(), form.getStaffUid())) {
            // 采购下单或是联营下单
            String bankApplyMsg = QyWeixinMsg.jointOperationBankApplyMsg(serverUrl, form.getStoreName(), form.getCode());
            QyWeiXinUtil.sendToUser(accessToken, agentid, thirdUserid, bankApplyMsg);
        } else {
            String bankApplyMsg = QyWeixinMsg.bankApplyMsg(serverUrl, form.getStoreName(), form.getCode());
            QyWeiXinUtil.sendToChat(accessToken, mallchatid, bankApplyMsg);
        }
        // 发送钉钉机器人群消息通知
        QyWeiXinUtil.sendToChat(accessToken, financechatid, QyWeixinMsg.bankCheckMsg(serverUrl, form.getStoreName(), form.getCode()));

        return R.ok();
    }


    @ApiOperation(value = "取消银行转账")
    @PostMapping(value = "/cancelBankPay", produces = "application/json; charset=UTF-8")
    public R<Object> cancelBankPay(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        OrderForm form = orderFormService.getByCode(staffUid, code);
        if (form == null)
            return R.fail("订单获取失败");
        if (!form.getStatus().equals(EnumType.OrderForm.APPLY_BANKPAY.getType()))
            return R.fail("订单状态不符合");

        boolean l = orderFormService.cancelBankPay(form.getStoreUid(), code);
        if (!l)
            return R.fail("操作失败");
        // 取消购物记录
        shopCartService.cancelShopCarts(null, code);

        // 删除图片记录
        long l1 = orderFormImageService.dropByOrderCode(code);
        if (l1 > 0) {
            // 删除图片文件
            List<OrderFormImage> imageList = orderFormImageService.getByOrderCode(code);
            if (CollectionUtils.isNotEmpty(imageList)) {
                List<String> urlList = imageList.stream().map(OrderFormImage::getImgUrl).collect(Collectors.toList());
                // 删除服务器上的截图
                LocalFileUtil.deleteImgList(LocalFileUtil.orderFormBaseDir, urlList);
            }
        }
        // 添加操作日志
        OrderFormLog log = OrderFormV3Util.newStaffLog(code, staffUid, staffName,
                EnumType.OrderForm.CANCEL_BANKPAY.getType(), "取消银行转账", "");
        orderFormLogService.saveOrUpdate(log);

        return R.ok();
    }

}
